/*
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package java.lang;

public final class StringBuffer implements CharSequence {
  public StringBuffer() {
    assign();
  }

  /**
   * This implementation does not track capacity; using this constructor is
   * functionally equivalent to using the zero-argument constructor.
   */
  public StringBuffer(int length) {
    assign();
  }

  public StringBuffer(String s) {
    assign(s);
  }

  private native StringBuffer assign() /*-{
    this.js = "";
    return this;
  }-*/;

  private native StringBuffer assign(String s) /*-{
    this.js = s;
    return this;
  }-*/;

  public native String toString() /*-{
    return this.js;
  }-*/;

  public native int length() /*-{
    return this.js.length;
  }-*/;

  public native StringBuffer append(String toAppend) /*-{
    this.js += toAppend;
    return this;
  }-*/;

  public native char charAt(int idx) /*-{
    return this.js.charCodeAt(idx);
  }-*/;

  public native String substring(int begin, int end) /*-{
    return this.js.substring(begin, end);
  }-*/;

  public String substring(int begin) {
    return substring(begin, length());
  }

  public native int indexOf(String s, int start) /*-{
    return this.js.indexOf(s, start);
  }-*/;

  public StringBuffer append(char[] chs, int offset, int len) {
    return append(String.valueOf(chs, offset, len));
  }

  public StringBuffer append(char[] chs) {
    return append(chs, 0, chs.length);
  }

  public StringBuffer append(Object x) {
    return append(String.valueOf(x));
  }

  public StringBuffer append(StringBuffer x) {
    return append(x == null ? "null" : x.toString());
  }

  public StringBuffer append(float x) {
    return append(String.valueOf(x));
  }

  public StringBuffer append(boolean x) {
    return append(String.valueOf(x));
  }

  public StringBuffer append(long x) {
    return append(String.valueOf(x));
  }

  public StringBuffer append(char x) {
    return append(String.valueOf(x));
  }

  public StringBuffer append(int x) {
    return append(String.valueOf(x));
  }

  public StringBuffer append(double x) {
    return append(String.valueOf(x));
  }

  public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
    while (srcBegin < srcEnd) {
      dst[dstBegin] = charAt(srcBegin);
      ++srcBegin;
      ++dstBegin;
    }
  }

  public int indexOf(String x) {
    return indexOf(x, 0);
  }

  public int lastIndexOf(String s) {
    return lastIndexOf(s, 0);
  }

  public native int lastIndexOf(String s, int start) /*-{
    return this.js.lastIndexOf(s, this.js.length - start);
  }-*/;

  public StringBuffer replace(int start, int end, String s) {
    return assign(substring(0, start) + (s != null ? s : "null")
      + substring(end));
  }

  public StringBuffer delete(int start, int end) {
    return assign(substring(0, start) + substring(end));
  }

  public StringBuffer deleteCharAt(int index) {
    return assign(substring(0, index) + substring(index + 1));
  }

  public StringBuffer insert(int index, char[] x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, char[] x, int offset, int len) {
    return assign(substring(0, index) + String.valueOf(x, offset, len)
      + substring(index));
  }

  public StringBuffer insert(int index, float x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, double x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, char x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, long x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, Object x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, boolean x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, String x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public StringBuffer insert(int index, int x) {
    return assign(substring(0, index) + String.valueOf(x) + substring(index));
  }

  public void setCharAt(int index, char x) {
    replace(index, index + 1, String.valueOf(x));
  }

  public void setLength(int newLength) {
    int oldLength = length();
    if (newLength < oldLength) {
      delete(newLength, oldLength);
    } else {
      while (oldLength < newLength) {
        append((char) 0);
        ++oldLength;
      }
    }

  }

  public CharSequence subSequence(int start, int end) {
    return this.substring(start, end);
  }
}
